package com.rayboot.footpoint.dialog;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.os.Handler;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.rayboot.footpoint.R;
import com.rayboot.footpoint.model.Footprint;
import com.rayboot.footpoint.utils.StorageUtil;
import com.rayboot.footpoint.utils.Util;
import com.rayboot.footpoint.utils.voice.Recorder;

public class AudioRecordDialog extends Dialog implements View.OnClickListener,
		DialogInterface.OnDismissListener {
	private static final String TAG = "AudioRecordDialog";
	private Button mCancelButton;
	private TextView mCurrentCount;
	private int mCurrentStatus = Recorder.IDLE_STATE;
	private TextView mDurationCount;
	private Footprint mFootprint = null;
	private ProgressBar mProgress;
	private Handler mProgressHandler = new Handler();
	private Button mRecordButton;
	private recordStateListener mRecordListener = null;
	private Recorder mRecorder;
	private long mRemainingTime = -1L;
	private Button mSaveButton;
	private StorageUtil mStorageUtil = null;
	Runnable mUpdateTimer = new Runnable() {
		@Override
		public void run() {
			AudioRecordDialog.this.updateTimerView();
		}
	};

	Recorder.OnStateChangedListener mediaListener = new Recorder.OnStateChangedListener() {

		@Override
		public void onStateChanged(int state) {
			// TODO Auto-generated method stub
			mCurrentStatus = state;
			// AudioRecordDialog.access$502(AudioRecordDialog.this, state);
			AudioRecordDialog.this.updateUI();
		}

		@Override
		public void onError(int errorCode) {
			// TODO Auto-generated method stub
			Resources localResources = AudioRecordDialog.this.getContext()
					.getResources();

			String msg = null;
			switch (errorCode) {
			case Recorder.SDCARD_ACCESS_ERROR:
				msg = localResources.getString(R.string.error_sdcard_access);
				break;
			case Recorder.INTERNAL_ERROR:
				msg = localResources.getString(R.string.error_app_internal);
				break;
			}

			if (msg != null) {
				new AlertDialog.Builder(AudioRecordDialog.this.getContext())
						.setTitle(R.string.app_name)
						.setIcon(android.R.drawable.ic_dialog_alert)
						.setMessage(msg)
						.setPositiveButton(R.string.button_ok, null)
						.setCancelable(false).show();
			}

		}
	};

	public AudioRecordDialog(Context context, int id, Footprint footprint) {
		super(context, id);
		this.mFootprint = footprint;
		init();
	}

	public AudioRecordDialog(Context context, Footprint footprint) {
		super(context);
		this.mFootprint = footprint;
		init();
	}

	private void calRecordingTime() {
		long leftStorage = StorageUtil.availableStorage();
		long leftTime;
		if (leftStorage > 0L) {
			leftTime = leftStorage / 135L;
			if (leftTime > 60L) {
				this.mRemainingTime = 60L;
			} else {
				this.mRemainingTime = leftTime;
			}
		} else {
			this.mRemainingTime = 0L;
		}
	}

	private void init() {
		getWindow().setBackgroundDrawable(new ColorDrawable());
		getWindow().requestFeature(
				WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW);
		initView();
		this.mStorageUtil = new StorageUtil(getContext()
				.getApplicationContext());
		this.mStorageUtil
				.SetOnChangeStorageListerner(new StorageUtil.OnChangeStorageListener() {
					@Override
					public void onStorageChanged(int state) {
						if (state > 1) {
							AudioRecordDialog.this.terminateRecording();
							AudioRecordDialog.this.dismiss();
						}
						AudioRecordDialog.this.mProgressHandler
								.post(new Runnable() {
									@Override
									public void run() {
										AudioRecordDialog.this
												.calRecordingTime();
										AudioRecordDialog.this.mDurationCount.setText(AudioRecordDialog.this
												.setupTimer(1000L * AudioRecordDialog.this.mRemainingTime));
									}
								});
					}
				});
		try {
			if (mFootprint.mAudioPath == null) {
				mRecorder = new Recorder();
			} else {
				mRecorder = new Recorder(mFootprint.mAudioPath);
			}
			this.mRecorder.setOnStateChangedListener(this.mediaListener);
			this.mProgressHandler.post(new Runnable() {
				@Override
				public void run() {
					AudioRecordDialog.this.calRecordingTime();
					AudioRecordDialog.this.mDurationCount.setText(AudioRecordDialog.this
							.setupTimer(1000L * AudioRecordDialog.this.mRemainingTime));
				}
			});
		} catch (NullPointerException localNullPointerException) {
			localNullPointerException.printStackTrace();
		}
	}

	private void initView() {
		setOnDismissListener(this);
		View localView = LayoutInflater.from(getContext()).inflate(
				R.layout.dialog_voice_record, null);
		this.mProgress = ((ProgressBar) localView
				.findViewById(R.id.pbVProgress));
		this.mDurationCount = ((TextView) localView
				.findViewById(R.id.tvVTotalTime));
		this.mDurationCount.setText(setupTimer(0L));
		this.mCurrentCount = ((TextView) localView
				.findViewById(R.id.tvVCurTime));
		this.mCurrentCount.setText(setupTimer(0L));
		this.mSaveButton = ((Button) localView.findViewById(R.id.btnVOK));
		this.mSaveButton.setOnClickListener(this);
		this.mCancelButton = ((Button) localView.findViewById(R.id.btnVCacel));
		this.mCancelButton.setOnClickListener(this);
		this.mRecordButton = ((Button) localView.findViewById(R.id.btnVRecord));
		this.mRecordButton.setOnClickListener(this);
		setContentView(localView);
		setCanceledOnTouchOutside(true);
	}

	private String setupTimer(long time) {

		if (time <= 0L) {
			return "00:00";
		}
		return String.format("%02d:%02d", Long.valueOf(time / 1000L / 60L),
				Long.valueOf(time / 1000L % 60L));
	}

	private void updateControlState(int state) {
		switch (state) {
		case 0:
			this.mRecordButton.setText(R.string.record_recording);
			this.mRecordButton
					.setBackgroundResource(R.drawable.bg_dialog_record_button);
			break;
		case 1:
			this.mRecordButton.setText(R.string.record_stop);
			this.mRecordButton
					.setBackgroundResource(R.drawable.bg_dialog_record_button_stop);
			break;
		case 2:
			break;
		default:
			break;
		}
	}

	private void updateTimerView() {
		int i;
		if (this.mCurrentStatus == Recorder.RECORDING_STATE) {
			if ((this.mCurrentStatus == Recorder.RECORDING_STATE)
					&& (this.mRecorder != null)) {
				this.mCurrentCount
						.setText(setupTimer(this.mRecorder.progress()));
				int progressMax = this.mProgress.getMax();
				if (this.mRemainingTime <= 0L) {
					this.mProgress.setProgress(0);
					this.mDurationCount.setText(setupTimer(-1L));
				} else {
					this.mProgress
							.setProgress((int) (progressMax
									* this.mRecorder.progress()
									/ this.mRemainingTime / 1000L));
					this.mDurationCount
							.setText(setupTimer(1000L * this.mRemainingTime));
				}

				if (this.mRecorder.progress() > 1000L * this.mRemainingTime) {
					terminateRecording();
					dismiss();
				} else {
					this.mProgressHandler.postDelayed(this.mUpdateTimer, 1000L);
				}
			}
		}
	}

	private void updateUI() {
		updateControlState(this.mCurrentStatus);
		updateTimerView();
	}

	@Override
	public void onDismiss(DialogInterface paramDialogInterface) {
		getWindow().clearFlags(WindowManager.LayoutParams.ALPHA_CHANGED);
		if (this.mStorageUtil != null) {
			this.mStorageUtil.closeStorgaeUtil();
		}
		if (mRecorder == null) {
			return;
		}

		mRecorder.stop();
		mRecorder = null;

		if (mFootprint == null || mRecorder.sampleFile() == null) {
			return;
		}

		this.mFootprint.mAudioPath = this.mRecorder.sampleFile()
				.getAbsolutePath();
		this.mFootprint.mAudioFileName = this.mRecorder.sampleFile().getName();
	}

	@Override
	protected void onStop() {
		if (mRecorder != null) {
			this.mRecorder.stop();
			this.mRecorder = null;
		}
		super.onStop();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if ((keyCode == KeyEvent.FLAG_KEEP_TOUCH_MODE)
				&& (event.getRepeatCount() == 0)) {
			terminateRecording();
			dismiss();
		}
		// while (true) {
		// return super.onKeyDown(paramInt, paramKeyEvent);
		// if (((paramInt != 19) && (paramInt != 20) && (paramInt != 21) &&
		// (paramInt != 22))
		// || (this.mRecordButton.isFocusable()))
		// continue;
		// this.mRecordButton.setFocusable(true);
		// this.mSaveButton.setFocusable(true);
		// this.mCancelButton.setFocusable(true);
		// }
		return super.onKeyDown(keyCode, event);
	}

	public void setRecordStatusListener(
			recordStateListener paramrecordStateListener) {
		if (paramrecordStateListener != null)
			this.mRecordListener = paramrecordStateListener;
	}

	public void terminateRecording() {
		getWindow().clearFlags(WindowManager.LayoutParams.ALPHA_CHANGED);
		if (mRecorder == null) {
			return;
		}
		mRecorder.stop();

		if (mRecorder.sampleFile() != null) {
			this.mFootprint.mAudioPath = this.mRecorder.sampleFile()
					.getAbsolutePath();
			this.mFootprint.mAudioFileName = this.mRecorder.sampleFile()
					.getName();
			this.mRecordListener.OnRecorded(recordStateListener.NEW_RECORD,
					this.mFootprint);
		}
		mRecorder = null;
	}

	public static abstract interface recordStateListener {
		public static final int NEW_RECORD = 1;
		public static final int NO_RECORD = 0;

		public abstract void OnRecorded(int state, Footprint footprint);
	}

	@Override
	public void onClick(View view) {
		// TODO Auto-generated method stub
		if (!view.isEnabled()) {
			return;
		}

		if (view == mSaveButton) {
			if (mCurrentStatus == Recorder.RECORDING_STATE) {
				Util.showToast(getContext(), R.string.stop_recording_first);
				return;
			}
			if (this.mRecorder.sampleFile() != null) {
				this.mFootprint.mAudioPath = this.mRecorder.sampleFile()
						.getAbsolutePath();
				this.mFootprint.mAudioFileName = this.mRecorder.sampleFile()
						.getName();
				this.mRecordListener.OnRecorded(recordStateListener.NEW_RECORD,
						this.mFootprint);
			}
			dismiss();
		} else if (view == this.mCancelButton) {
			if (this.mCurrentStatus == Recorder.RECORDING_STATE) {
				Util.showToast(getContext(), R.string.stop_recording_first);
				return;
			}
			this.mRecordListener.OnRecorded(recordStateListener.NO_RECORD,
					this.mFootprint);
			dismiss();
		} else if (view == mRecordButton) {
			if (!StorageUtil.isExternalStorageEnough()
					&& !StorageUtil.isInternalStorageEnough()) {
				Util.showToast(getContext(), R.string.text_not_enough_space);
			}

			if (this.mCurrentStatus == Recorder.IDLE_STATE) {
				this.mRecorder.startRecording();
				getWindow().addFlags(WindowManager.LayoutParams.ALPHA_CHANGED);
			} else {
				updateUI();
				this.mRecorder.stopRecording();
				getWindow().addFlags(WindowManager.LayoutParams.ALPHA_CHANGED);
			}
		}
	}

}
